package com.xizi.lotterySystem.service.activitystatus.impl;

import com.xizi.lotterySystem.common.exception.ServiceException;
import com.xizi.lotterySystem.common.exception.errorCode.ServiceErrorCodeConstants;
import com.xizi.lotterySystem.service.IActivityService;
import com.xizi.lotterySystem.service.activitystatus.IActivityStatusManager;
import com.xizi.lotterySystem.service.activitystatus.operator.AbstractActivityOperator;
import com.xizi.lotterySystem.service.dto.ConvertActivityStatusDTO;
import com.xizi.lotterySystem.utils.JacksonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Service
public class ActivityStatusManagerImpl implements IActivityStatusManager {

    private static final Logger log = LoggerFactory.getLogger(ActivityStatusManagerImpl.class);


    @Autowired
    private final Map<String, AbstractActivityOperator> operatorMap = new HashMap<>() ;

    @Autowired
    private IActivityService activityService;

    @Override
    public Boolean handlerEvent(ConvertActivityStatusDTO param) {
        if(operatorMap.size() == 0){
            log.error("operatorMap.size() = 0, 无法进行后续操作！");
            return false;
        }

        Map<String, AbstractActivityOperator> statusManagerMap = new HashMap<>(operatorMap);
        Boolean update = false;
        // 按优先级 更新状态
        //   1.先更新 中奖人 和 奖品
        update = processConvertStatus(1,param,statusManagerMap);
        //   2.更新  活动状态
        update = processConvertStatus(2,param,statusManagerMap) || update;
        //修改 Redis 中信息， 保证  Redis 中缓存的数据与数据库中一致
        if(update == true){
            activityService.updateCacheActivityDetail(param.getActivityId());
        }
        return true;
    }

    @Override
    public Boolean rollbackHandlerEvent(ConvertActivityStatusDTO param) {
        if(operatorMap.size() == 0){
            log.error("operatorMap.size() = 0, 无法进行后续操作！");
            return false;
        }

        Map<String, AbstractActivityOperator> statusManagerMap = new HashMap<>(operatorMap);
        Boolean update = false;

        for (AbstractActivityOperator operator : statusManagerMap.values()) {
            operator.convert(param);
        }
        activityService.updateCacheActivityDetail(param.getActivityId());
        return true;
    }

    private Boolean processConvertStatus(int sequence,
                                      ConvertActivityStatusDTO param,
                                      Map<String, AbstractActivityOperator> operatorMap) {
        Boolean update = false;
        Iterator<Map.Entry<String, AbstractActivityOperator>> iterator = operatorMap.entrySet().iterator();

        while(iterator.hasNext()){
            AbstractActivityOperator operator = iterator.next().getValue();
            // 判断是否  需要  转换状态
            if(operator.sequence() != sequence || !operator.needConvert(param)){
                log.info(JacksonUtil.writeValueAsString(operator));
                continue;
            }
            // 开始转换状态
            Boolean convert = operator.convert(param);
            if(convert == false){
                log.error(ServiceErrorCodeConstants.ACTIVITY_CONVENT_ERROR.getMessage());
                throw new ServiceException(ServiceErrorCodeConstants.ACTIVITY_CONVENT_ERROR);
            }
            // 移除
            iterator.remove();
            update = true;
        }

        return update;
    }

}
